﻿#include "qlua.h"

QLua::QLua(QObject *parent) :
    QObject(parent)
  , L(NULL)
  , isStartModule(false)
{
    init();
}

QLua::~QLua()
{
    close();
}

void QLua::init()
{
    L = luaL_newstate();
    luaL_openlibs(L);
}

void QLua::close()
{
    if(L != NULL)
    {
        lua_close(L);
        L = NULL;
    }
}

void QLua::pushFunction(QString funcName, lua_CFunction func)
{
    if (funcName.isEmpty()) return;
    if (func == NULL)       return;

    lua_pushcfunction(L, func);
    lua_setglobal(L, funcName.toLocal8Bit().data());
}

void QLua::getGlobal(QString value)
{
    lua_getglobal(L, value.toLocal8Bit().data());
}

void QLua::pushNumber(lua_Number value)
{
    lua_pushnumber(L, value);
}

void QLua::beginModule(QString name)
{
    if(L == NULL) return;

    if (isStartModule == false)
    {
        tolua_open(L);
        tolua_module(L, NULL, 0);
        isStartModule = true;
    }

    const char *str = name.isEmpty()? NULL : name.toLocal8Bit().data();
    tolua_beginmodule(L, str);
}

void QLua::addType(QString name, lua_CFunction deleteFunc)
{
    if (L == NULL) return;
    if (name.isEmpty())   return;
    if (deleteFunc == NULL) return;

    tolua_usertype(L, name.toLocal8Bit().data());
    const char *str = name.toLocal8Bit().data();
    tolua_cclass(L, str, str, "", deleteFunc);
    beginModule(name);
}

void QLua::moduleTypeFunction(QString name, lua_CFunction func)
{
    if(L == NULL) return ;
    if (name.isEmpty())  return;

    const char *str = name.toLocal8Bit().data();
    tolua_function(L, str, func);
}

void QLua::endModule()
{
    tolua_endmodule(L);
}

void QLua::run(QString str)
{
    luaL_loadbuffer(L, str.toLocal8Bit().data(), str.length(), "line");
    lua_pcall(L, 0, 0, 0);
}

void QLua::loadFile(QString fileName)
{
    QFile file(fileName);
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString code = in.readAll();
    run(code);
}

void QLua::pcall(int nargs, int nresults, int errfunc)
{
    lua_pcall(L, nargs, nresults, errfunc);
}

bool QLua::isNumber(int idx)
{
    return lua_isnumber(L, idx);
}

double QLua::toNumber(int idx)
{
    return lua_tonumber(L, idx);
}

void QLua::pushString(QString value)
{
    lua_pushstring(L, value.toLocal8Bit().data());
}

bool QLua::isString(int idx)
{
    return lua_isstring(L, idx);
}

QString QLua::toString(int idx)
{
    return QString::fromLocal8Bit(lua_tostring(L, idx));
}

void QLua::pop(int num)
{
    lua_pop(L, num);
}
